#include "LogicDelete.h"

Display LogicDelete::deleteTaskByString( string searchType ) {

	string term;
	bool typeName;
	bool typeSearchTerm;

	typeName = isDeleteByName(term);
	typeSearchTerm = isDeleteBySearchTerm(term);

	if( typeName ) {
		_display = deleteTaskByName( term );
	} else if( typeSearchTerm ) {
		_display = deleteTaskBySearchTerm( term );
	}

	return _display;
}

Display LogicDelete::deleteTaskByIndex( int index ) {
	
	string statusMessage;
	Data::DataFeedback dataFeedback;
	vector<Task> display;
	vector<Task> tasks;
	bool outOfBounds;
	stringstream displayMsg;
	
	outOfBounds = isOutOfBounds(index, _display.getDisplaySize());
	
	if( outOfBounds ) {
		throw(INDEX_OUT_OF_BOUNDS_ERROR_MESSAGE);
	}

	display = _display.getTaskList();

	int taskId = display[index-1].getTaskID();

	displayMsg << display[index-1].getTaskName();

	dataFeedback = _data->executeDeleteTaskID(taskId);

	if( dataFeedback == Data::SUCCESS ) {
		display.erase(display.begin()+index-1);
		_data->getAll(tasks);
		_writer->write(tasks);
		statusMessage = DELETE_SUCCESS_MESSAGE + displayMsg.str();
	} else {
		statusMessage = DELETE_ERROR_MESSAGE;
	}

	_display = Display( statusMessage, display );

	return _display;
}

Display LogicDelete::deleteTaskByName( string taskName ) {

	string statusMessage;
	int taskId;
	Data::DataFeedback dataFeedback;
	vector<Task> display;
	vector<Task> tasks;
	bool multipleMatch;
	bool executed;
	stringstream displayMsg;

	dataFeedback = _data->getByName(tasks ,taskName);
	
	if( tasks.empty() ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}

	multipleMatch = isMultipleMatches(tasks.size());

	if( multipleMatch ) {
		display = tasks;
		executed = false;
	} else {
		taskId = tasks[FIRST_POSITION].getTaskID();
		display = _display.getTaskList();
		// if task is in the display, remove it.
		for( unsigned int i=0; i<display.size(); i++ ) {
			if( display[i].getTaskID() == taskId ) {
				display.erase(display.begin()+i);
			}
		}
		displayMsg << tasks[FIRST_POSITION].getTaskName();
		dataFeedback = _data->executeDeleteTaskID(taskId);
		executed = true;
	}

	if( executed == true && dataFeedback == Data::SUCCESS ) {
		tasks.clear();
		_data->getAll(tasks);
		_writer->write(tasks);
		statusMessage = DELETE_SUCCESS_MESSAGE + displayMsg.str();
	} else {
		statusMessage = DELETE_ERROR_MESSAGE;
	}

	_display = Display( statusMessage, display );

	return _display;
}

Display LogicDelete::deleteTaskBySearchTerm( string searchTerm ) {
	
	string statusMessage;
	int taskId;
	Data::DataFeedback dataFeedback;
	vector<Task> display;
	vector<Task> tasks;
	bool multipleMatch;
	bool executed;
	stringstream displayMsg;

	dataFeedback = _data->getBySearchTerm(tasks, searchTerm);
	
	if( tasks.empty() ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}

	multipleMatch = isMultipleMatches(tasks.size());

	if( multipleMatch ) {
		display = tasks;
		executed = false;
	} else {
		taskId = tasks[FIRST_POSITION].getTaskID();
		display = _display.getTaskList();
		// if task is in the display, remove it.
		for( unsigned int i=0; i<display.size(); i++ ) {
			if( display[i].getTaskID() == taskId ) {
				display.erase(display.begin()+i);
			}
		}
		displayMsg << tasks[FIRST_POSITION].getTaskName();
		dataFeedback = _data->executeDeleteTaskID(taskId);
		executed = true;
	}

	if( executed == true && dataFeedback == Data::SUCCESS ) {
		tasks.clear();
		_data->getAll(tasks);
		_writer->write(tasks);
		statusMessage = DELETE_SUCCESS_MESSAGE + displayMsg.str();
	} else {
		statusMessage = DELETE_ERROR_MESSAGE;
	}

	_display = Display( statusMessage, display );

	return _display;
}

Display LogicDelete::deleteDoneTask( bool done ) {

	string statusMessage;
	int taskId;
	Data::DataFeedback dataFeedback;
	vector<Task> tasks;	

	dataFeedback = _data->getByDone(tasks);
	
	if( dataFeedback == Data::NOT_FOUND ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}

	for( unsigned int i=0; i<tasks.size(); i++ ) {
		taskId = tasks[i].getTaskID();
		dataFeedback = _data->executeDeleteTaskID(taskId);
	}

	if(dataFeedback == Data::SUCCESS ) {
		tasks.clear();
		_data->getAll(tasks);
		_writer->write(tasks);
		statusMessage = DELETE_DONE_SUCCESS_MESSAGE;
	} else {
		statusMessage = DELETE_ERROR_MESSAGE;
	}

	_display = Display( statusMessage, tasks );

	return _display;
}

// this function determines whether it deletes by done
// returns TRUE if term matches keyword done
// returns FALSE otherwise
bool LogicDelete::isDeleteByDone(string term) {
	
	bool isDeleteTypeDone;
	if( term == DELETE_TYPE_DONE ) {
		isDeleteTypeDone = true;
	} else {
		isDeleteTypeDone = false;
	}

	return isDeleteTypeDone;
}

bool LogicDelete::isDeleteByName( string term )
{

	bool isDeleteTypeName;

	vector<Task> tasks;
	_data->getByName(tasks, term);

	if( tasks.empty() ) {
		isDeleteTypeName = false;
	} else {
		isDeleteTypeName = true;
	}

	return isDeleteTypeName;
}

bool LogicDelete::isDeleteBySearchTerm( string term )
{

	bool isDeleteSearchTerm;

	vector<Task> tasks;
	_data->getBySearchTerm(tasks, term);

	if( tasks.empty() ) {
		isDeleteSearchTerm = false;
	} else {
		isDeleteSearchTerm = true;
	}

	return isDeleteSearchTerm;
}

const string LogicDelete::DELETE_SUCCESS_MESSAGE = "Task Deleted: ";

const string LogicDelete::DELETE_DONE_SUCCESS_MESSAGE = "Done Tasks Deleted";

const string LogicDelete::DELETE_ERROR_MESSAGE = "Unable To Delete";

const string LogicDelete::DELETE_TYPE_DONE = "done";

const int LogicDelete::FIRST_POSITION = 0;